#pragma once

#include "zen_app.h"
#include "zen_ticker.h"
#include <vector>
#include <mutex>
#include "zen_vap_node.h"

namespace Zen { namespace Vap {

	class RootDelegate : public AppDelegate {};

	/*!
	 @class
	 @abstract touch information. `AppTouch` and attached node.
	 */
	struct TouchInfo {
		AppTouch touch;
		std::weak_ptr<Node> attached_node;
	};

	/*!
	 @class Activity
	 @abstract Activity is the root node of a game instance. this is singleton.
	 @discussion for a game app, the entance use `ZenAppMain` (see ref Zen::App)
	example:
	 ```
	 class MainDelegate : public Zen::Vap::RootDelegate
	 {
	 	// TODO:...
	 };
	 int ZenAppMain(int argc, const char ** argv)
	 {
		 auto root = Zen::Vap::Activity::Get();
		 root->setDelegate(std::make_shared<MainDelegate>());
		 Zen::App::Get()->setRuntimeDelegate(root);
		 Zen::App::Get()->setRotatable(true);
		 Zen::App::Get()->setBGUpdate(true);

		 return 0;
	 }
	 ```
	 */
	class Activity : public AppDelegate {

	public:
		static std::shared_ptr<Activity> Get();

		/*!
		 @function setDelegate
		 @abstract set delegate to access Events.
		 - start the game scenes in the overrided RootDelegate::onLaunch.
		 - must setDelegate in `ZenAppMain` entrance, to receive `onLaunch` event.
		 @param _ the delegate
		 */
		virtual void setDelegate(std::shared_ptr<RootDelegate> _) = 0;

		/*!
		 @function getDelegate
		 @abstract get current delegate.
		 */
		virtual std::shared_ptr<RootDelegate> getDelegate() = 0;

	public: // below functions not valid before onLaunch.
		/*!
		 @function getRealViewSize
		 @abstract get the device screen size.(pixels count)
		 */
		virtual Size2 getRealViewSize() = 0;

		/*!
		 @function setBackgroundColor
		 @abstract set background color (the clear color)
		 */
		virtual void setBackgroundColor(Color4f const & color) = 0;
		
		virtual Color4f getBackgroundColor() = 0;

		/**
		 total running time ( not includes paused time)
		 */
		virtual double getRunningTime() = 0;

		/**
		 total time since app started (includes paused time).
		 */
		virtual double getTotalTime() = 0;

		virtual std::shared_ptr<Node> getRootNode() = 0;

		virtual std::map<uint32_t, TouchInfo> const & getTouches() = 0;
	protected:
		Activity() = default;

		virtual ~Activity() = default;
	};
}}
